\documentclass[a4paper]{article}
\usepackage{tpCaml}
\usepackage[frenchb]{babel}
\usepackage[utf8]{inputenc}
\usepackage{csquotes} % csquotes va utiliser la langue
%\usepackage[T1]{fontenc}

% vous pouvez modifier ces valeurs, à condition de ne pas dépasser 25.5cm de hauteur !
\textwidth 16cm
\textheight 24cm
\headsep 0.8cm
\topmargin -1.5cm
\oddsidemargin 0cm

\begin{document}

\enteteTPcaml{4}{oct. 2012}{Ordre supérieur}

\section{Consignes de rendu}

A la fin de ce TP vous devrez rendre une archive de la forme
\textbf{rendu-tp4-login\_x.zip}. Il va de soi que ``login\_x'' est a
remplacé par le vôtre. \\

L'intérieur de l'archive contiendra un dossier ``login\_x'' avec les
fichiers demandé pour le TP ainsi que un AUTHORS du format ``*
login\_x'' suivis d'un retour à la ligne.\\

Arborescence du fichier :\\
login\_x\ \\
\indent |- AUTHORS \\
\indent |- repertoire.ml \\

De plus pour simplifier les arguments qu'on va passer en parametre,
nous allons les ``renommer'', rajouter ces lignes en debut de votre
fichier, et bien sur les utiliser pour la suite. \\

\begin{alltt}
    type name = string
    type age = int
    type adress = string
    type telephone = int
    type contact = (name * age * adress * telephone)
    type agenda = contact list
\end{alltt}

\section{L'ordre supérieur, c'est quoi ?}

\enquote{En mathématiques et en informatique, les fonctions d'ordre
  supérieur ou les fonctionnelles sont des fonctions qui ont au moins
  une des propriétés suivantes :
  \begin{itemize}
  \item prendre une ou plusieurs fonctions comme entrée
  \item renvoyer une fonction
  \end{itemize} 
}
\begin{flushright}
  [Wikipedia]
\end{flushright}

Pour résumer en une seule phrase, le principe est de passer à une
fonction une autre fonction comme argument. Et par chance \caml est
un langage fonctionnel, vous allez pouvoir vous amusez !   


\section{Boites à outils}

\subsection{Les listes}

Avant de commencer, quelques petites fonctions sur les listes pour
s'échauffer. Nous en aurons besoin pour la suite du TP ne les négligez
pas !

\paragraph{add\_list}
~~\\
La fonction \ml{add\_list} va ajouter un élément x dans une liste l
et la renvoyer. 
\begin{alltt}
  \rep{val add\_list : 'a -> 'a list -> 'a list = <fun> }
\end{alltt}


\paragraph{remove\_list}
~~\\
La fonction \ml{remove\_list}, tout comme son nom l'indique, va
retirer l'élément x de la liste l.
\begin{alltt}
  \rep{val remove\_list : 'a -> 'a list -> 'a list = <fun> }
\end{alltt}  

\paragraph{exist}
~~\\
La fonction va vérifier si l'élément x est présent dans la liste
passé en paramètre pour renvoyer \ml{true} si l'élément est trouvé
et \ml{false} dans le cas contraire.
\begin{alltt}
  \rep{val exist : 'a -> 'a list -> bool = <fun>}
\end{alltt}

\subsection{Introduction des fonctions sur l'ordre supérieur}

\paragraph{map}
~~\\
La fonction \ml{map} va appliquer la fonction f à tous les éléments
de la liste l pour ensuite renvoyer la liste modifié.
\begin{alltt}
  \rep { val map : ('a -> 'b) -> 'a list -> 'b list = <fun>}
\end{alltt}

  \emph{Exemple d'application : }
  \begin{alltt}
    \sh map (function x -> x + 1) [1;3;5;7;11];;
       {\rep - : int list = [2;4;6;8;12]}
 \end{alltt}

\paragraph{iter}
~~\\
La fonction \ml{iter} prend en arguments une fonction et une liste et
applique cette fonction à tous les éléments de la liste.
\begin{alltt}
  \rep { val iter : ('a -> 'b) -> 'a list -> unit = <fun>}
\end{alltt}

  \emph{Exemple d'application : }
  \begin{alltt}
    \sh iter (print_int) [1;3;5;7;11];;
       {\rep 135711- : unit = ()}
 \end{alltt}

\paragraph{for\_all}
~~\\
La fonction for\_all prend en arguments une fonction booléenne et une liste et 
renvoie vrai si pour tous les éléments X de la liste f X = true.
\begin{alltt}
  \rep {val for\_all : (’a -> bool) -> ’a list -> bool = <fun>}
\end{alltt}

  \emph{Exemple d'application : }
  \begin{alltt}
    \sh for\_all (function x -> x = 0) [0;0;0;0;0];;
       {\rep - : bool = true}
 \end{alltt}

\subsection{Manipulation des caractères}

\paragraph{upper\_case}
~~\\
La fonction \ml{upper\_case} va passer un caractère en majuscule. Vous
pouvez vous aider du code ASCII.
\begin{alltt}
  \rep {val upper\_case : char -> char = <fun>}
\end{alltt}

  \emph{Exemple d'application : }
  \begin{alltt}
    \sh upper\_case 'c';;
       {\rep - : char = 'C'}
 \end{alltt}


\paragraph{lower\_case}
~~\\
Vis vers ça pour lowercase, elle va mettre un caractère en minuscule. 
\begin{alltt}
  \rep {val lower\_case : char -> char = <fun>}
\end{alltt}

  \emph{Exemple d'application : }
  \begin{alltt}
    \sh lower\_case 'C';;
       {\rep - : char 'c'}
 \end{alltt}


\subsection{Manipulation des chaines}
Nous allons aborder un point tout nouveau, le parcours de chaine de
caractère. Les chaines de caractères, dont leur type est ``string'',
est en fait un tableau de caractères. Par exemple la string \ml{let str = ``Hello
  world!''} contient 13 caractères, donc la taille du tableau est de
13 cases. Tout comme pour les listes on reste en base 0, donc le dernier
élément serait longueur - 1. Si on voudrait  récupérer le premier
caractère de str il suffirait de faire \ml{str.[0]}.\\

\paragraph{string\_apply}
~~\\
Vous allez pouvoir maintenant implémenter la fonction qui va
appliquer à chaque caractères la fonction f. 
\begin{alltt}
  \rep{val string_apply : (char -> char) -> string -> string = <fun>}
\end{alltt}

Vous pourrez utiliser les fonctions suivantes :\\

\noindent \ml{val String.length : string -> int}\\
\indent Return the length (number of characters) of the given string.
\\\\
\noindent \ml{let string\_of\_char c = String.make 1 c ;;}
\indent Permet de transformer un caractère du type char à string.

\paragraph{string\_uppercase}
~~\\
La fonction \ml{string\_uppercase} va mettre toute la chaine de
caractère en majuscule. Vous devez utiliser les fonctions déjà réalisé.
\begin{alltt}
  \rep{val string_uppercase : string -> string = <fun>}
\end{alltt}


  \emph{Exemple d'application : }
  \begin{alltt}
    \sh string\_uppercase 'Hello';;
       {\rep - : string 'HELLO'}
 \end{alltt}

\paragraph{string\_lowecase}
~~\\
Inversement pour cette fonction, elle va la mettre en minuscule. Vous
devez utiliser les fonctions déjà réalisé.
\begin{alltt}
  \rep{val string_lowercase : string -> string = <fun>}
\end{alltt}


  \emph{Exemple d'application : }
  \begin{alltt}
    \sh string\_lowercase 'HElLO';;
       {\rep - : string 'hello'}
 \end{alltt}

\paragraph{convert\_first\_maj}
~~\\
Cette fonction va mettre la première lettre de la chaine de
caractère en majuscule. Utiliser les fonctions vues plus haut.
\begin{alltt}
  \rep{val convert\_first\_maj : string -> string = <fun>}
\end{alltt}


  \emph{Exemple d'application : }
  \begin{alltt}
    \sh convert\_first\_maj 'hello';;
       {\rep - : string 'Hello'}
 \end{alltt}

\section{Création du répertoire}

\paragraph{create\_contact}
~~\\
Cette fonction va créer un contact sans le mettre dans la liste et le
mettre en forme pour le préparer à son insertion. Le nom doit être en minuscule sauf la première lettre.
\begin{alltt}
  \rep{val create_contact : string * 'a * 'b * 'c -> string * 'a * 'b * 'c = <fun>}
\end{alltt}

\paragraph{manage\_contact}
~~\\
Cette fonction va appliquer la fonction f a tous les contacts de
l'agenda. Vous allez en avoir besoin pour les fonctions suivantes
\begin{alltt}
  \rep{val manage_contact : ('a -> 'b -> 'c) -> 'a -> 'b -> 'c = <fun>}
\end{alltt}

\paragraph{add\_contact}
~~\\
La fonction va rajouter un contact dans l'agenda, si le contact
n'existe pas et afficher un message d'erreur dans le cas où il
existe.
\begin{alltt}
  \rep{val add_contact : string * 'a * 'b * 'c -> (string * 'a * 'b * 'c) list -> (string * 'a * 'b * 'c) list = <fun>}
\end{alltt}

\paragraph{remove\_contact}
~~\\
La fonction va vérifier si le contact est présent dans la liste et
si c'est le cas il va enlever le contact en affichant un message
confirmant la  suppression sinon un message d'erreur dans le cas contraire.
\begin{alltt}
  \rep{val remove\_contact : 'a -> 'a list -> 'a list = <fun>}
\end{alltt}

\paragraph{edit\_contact}
~~\\
La fonction \ml{edit\_contact} va prendre comme argument le nom pour trouver le
contact ainsi que la nouvelle fiche contact qui remplacera l'ancienne.
\begin{alltt}
  \rep{val edit_contact : 'a -> 'a * 'b * 'c * 'd -> ('a * 'b * 'c * 'd) list -> ('a * 'b * 'c * 'd) list = <fun>}
\end{alltt}

\paragraph{is\_good\_format}
~~\\
Cette fonction va vérifier si tous les noms dans le répertoire à une majuscule.
Vous devez utiliser les fonctions de l'ordre supérieur vu au début (map, iter, for\_all).
\begin{alltt}
  \rep {val isgoodformat : ('a -> bool) -> 'a list -> unit = <fun>}
\end{alltt}

\paragraph{print\_agenda}
~~\\
Et maintenant la fonction principal, et la plus importante :
l'affichage. Vous allez pouvoir voir si votre agenda fonctionne (ou
pas) !
Cette fonction va prendre votre agenda en paramètre puis afficher
chaque contact en la parcourant.
\begin{alltt}
  \rep { val print_agenda : (string * string * string * string) list -> unit = <fun>}
\end{alltt}

\newpage
\section{Bonus}

Vous avez terminé votre sujet et vous voulez en apprendre un peu plus
sur les listes et vous avancez un peu sur vos cours d'algorithmie,
vous avez la  possibilité de faire plusieurs tri de liste.
\begin{itemize}
\item Bubble sort 
\item Tri par selection
\item Merge sort
\end{itemize}


%%%%%%%%%%%%%%%%%%%%%%%%

%  Pour la plupart des fonctions \caml à écrire, il est utile de
%  donner le type :

%  \begin{alltt}
%    {\rep val fact : int -> int = <fun>}
%  \end{alltt}

%  On peut aussi dans certains cas donner un exemple d'application.

%  \emph{Exemple d'application : }
%  \begin{alltt}
%    \sh let pi = map (String.length)
%        ["que";"j";"aime";"à";"faire";"apprendre";"ce";"nombre";"utile";"aux";"sages"];;
%       {\rep val pi : int list = [3; 1; 4; 1; 5; 9; 2; 6; 5; 3; 5] }
% \end{alltt}

%  Lorsqu'il y a besoin d'utiliser des fonctions de \caml (ou de les recoder), on recopie le contenu du manuel (in english!).\\
%
%  \noindent \ml{val rlineto : dx:int -> dy:int -> unit}\\
%  \indent Draw a line with endpoints the current point and the
%  current point translated of the given vector, and move the
%  current point to this point.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\end{document}
